package cn.sc.summer.gateway.config;

import cn.sc.summer.constant.token.AuthProperties;
import cn.sc.summer.gateway.filter.ApiAuthFilter;
import cn.sc.summer.gateway.webfilter.AuthFilter;
import cn.sc.summer.gateway.webfilter.CorsWebFilter;
import cn.sc.summer.token.handler.gateway.AccessDeniedHandlerX;
import cn.sc.summer.token.handler.gateway.AuthenticationEntryPointX;
import cn.sc.summer.token.properties.TokenMaxProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;

import javax.annotation.Resource;

/**
 * 类名：网关认证
 *
 * @author a-xin
 * @date 2024/8/19 11:17
 */
@Slf4j
@Configuration
@EnableWebFluxSecurity
public class SecurityGatewayConfig {

    @Resource
    private AuthProperties authProperties;

    @Resource
    private TokenMaxProperties tokenMaxProperties;

    @Bean
    public SecurityWebFilterChain webFluxSecurityFilterChain(ServerHttpSecurity http) {
        log.info("==> The gateway security web filterChain create...");

        http.authorizeExchange().pathMatchers("/")
                .permitAll()
                .anyExchange()
                .access(new ResourceManager());

        //异常处理
        http.exceptionHandling()
                .authenticationEntryPoint(new AuthenticationEntryPointX())
                .accessDeniedHandler(new AccessDeniedHandlerX());

        http.addFilterAt(new CorsWebFilter(authProperties), SecurityWebFiltersOrder.CORS);

        http.addFilterAt(new AuthFilter(authProperties, tokenMaxProperties), SecurityWebFiltersOrder.AUTHENTICATION);
        http.addFilterAfter(new ApiAuthFilter(authProperties), SecurityWebFiltersOrder.AUTHENTICATION);

        http.csrf().disable();
        http.httpBasic().disable();

        return http.build();
    }

}
